package org.jeecg.modules.xxgx.common.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xkcoding.http.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.commons.math.util.MathUtils;
import org.jeecg.modules.common.util.StringUtilsExt;
import org.jeecg.modules.common.util.MathUtil;
import org.jeecg.modules.innerApi.common.requestDto.InvoiceParam;
import org.jeecg.modules.innerApi.common.requestDto.InvoicemxParam;
import org.jeecg.modules.xxgx.common.enums.FphxzEnum;
import org.jeecg.modules.xxgx.common.vo.HsBhsConvertVo;
import org.jeecg.modules.xxgx.djgl.constant.CustomConst;
import org.jeecg.modules.xxgx.djgl.constant.NumberConstant;
import org.jeecg.modules.xxgx.djgl.constant.StringConstant;
import org.jeecg.modules.xxgx.djgl.entity.CsXxDkdjmx;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 发票工具类
 */
public class FPUtil {
	private static int digitLen=8;
	//需要认证的发票类型：增值税专用发票:004,机动车发票:005,通行费电子发票:092,电子专票:028
	public static final String NEED_AUTH_FPLXDM = "10100,10104,10107";
	//默认可以抵扣的发票类型：10100增值税专用发票,10104机动车销售统一发票,10107增值税电子专用发票,10200火车票,10202飞机行程单,10204通行费发票
	public static final String NEED_DK_FPLXDM = "10100,10104,10107,10200,10202,10204";
	/**
	 * 广西五菱可记账的发票类型 (增值税专用发票、增值税电子普通发票、增值税电子专用发票、区块链发票、通用机打发票、机动车销售统一发票)
	 */
	public static final String BOOK_KEEPING_INVOICE_TYPE_WL = "10100,10102,10107,10108,10400,10104";

	/**
	 * 增值税类型发票的计算方式的发票种类
	 */
	public static final String VAT_INVOICE_CACULATION_TYPE = "10100,10101,10102,10103,10104,10107";
	/**
	 * 飞机行程计算类型的发票种类
	 */
	public static final String Flight_Itinerary_INVOICE_CACULATION_TYPE = "10202";
	/**
	 * 不需要计算税额发票种类
	 */
	public static final String WITHOUT_CALCULATE_TYPE = "10604";

	/**
	 * 查验后需更新发票信息的发票种类
	 */
	public static final String AFTER_CHECK_UPDATE = "10100,10101,10102,10103,10104,10105,10107,10109,1010901,1010902";

	/**
	 * 可以勾选的发票类型（抵账库中的发票类型）
	 * 增值税专用发票:10100,机动车发票:10104,全电专票:1010901,增值税电子专用发票：10107，海关缴款书：17
	 * 通行费电子发票（需额外判断，增值税电子普通发票，发票代码后两位为12）
	 */
	public static final String NEED_TICK_FPLXDM = "10100,10104,10107,1010901,17";

	//全电票抬头
	public final static String ALL_ELECTRIC_INVOICE_TITLE_COMMON = "电子发票(普通发票)";
	public final static String ALL_ELECTRIC_INVOICE_TITLE_SPECIAL = "电子发票(增值税专用发票)";

	public final static String ALL_ELECTRIC_INVOICE_CODE_COMMON = "1010902";
	public final static String ALL_ELECTRIC_INVOICE_CODE_SPECIAL = "1010901";

	//不征税
	public final static String TAX_RATE_CODE_NO = "101";
	public final static String TAX_RATE_TEXT_NO = "不征税";
	//免税
	public final static String TAX_RATE_CODE_EXEMPT = "102";
	public final static String TAX_RATE_TEXT_EXEMPT = "免税";
	//部分含税
	public final static String TAX_RATE_CODE_PART = "103";
	public final static String TAX_RATE_TEXT_PART = "***";
	//多税率
	public final static String TAX_RATE_CODE_MULTIPART = "104";
	public final static String TAX_RATE_TEXT_MULTIPART = "多税率";

	public final static String[] SPECIAL_TAX_RATE = {"不征税","免税","***"};

	/**
	 * 单据明细默认合并替换
	 */
	public final static String ORDER_DETAIL_DEFAULT_COMBINE_RULE = "spmc,ggxh,jldw,tax";
	/**
	 * 鉴别发票的类型 004-专票  007-普票  025-卷票  026-电子发票
	 * @param fpdm 发票代码
	 * @return
	 */
	public static String identifyCategory(String fpdm){
		String fplx ="000";
		String fpdmCut="";
		if(fpdm.length() == 12){
			fpdmCut = fpdm.substring(10,12);
			if("04".equals(fpdmCut) || "05".equals(fpdmCut)){
				fplx ="007";
			}else if("11".equals(fpdmCut) || "12".equals(fpdmCut)){
				fplx ="026";
			}else if("06".equals(fpdmCut) || "07".equals(fpdmCut)){
				fplx ="025";
			}
		}else if(fpdm.length() == 10){
			fpdmCut = fpdm.substring(8,9);
			if("3".equals(fpdmCut) || "6".equals(fpdmCut)){
				fplx ="004";
			}else if("2".equals(fpdmCut) || "5".equals(fpdmCut)){
				fplx ="007";
			}
		}
		return fplx;
	}
	// 转换发票类型为中文
	public static String convertDmToZh(String fpdm){
		if(StringUtil.isEmpty(fpdm)){
			return "";
		}
		// 004-专票  007-普票  025-卷票  026-电子发票
		String zh = fpdm;
		switch (fpdm){
			case "01":
				zh="数电专票";
				break;
			case "02":
				zh="数电普票";
				break;
			case "004":
				zh="专票";
				break;
			case "007":
				zh="普票";
				break;
			case "025":
				zh="卷票";
				break;
			case "026":
				zh="电子普票";
				break;
			case "028":
				zh="电子专票";
				break;
			case "005":
				zh="机动车发票";
				break;
			default:
				zh = fpdm;
		}
		return zh;
	}

	public static Date getDate(String date) {
		if ("".equals(date)) {
			return null;
		}

		String dateStr = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8) + " " + date.substring(8, 10) + ":" + date.substring(10, 12) + ":" + date.substring(12, 14);

		try {
			return DateUtils.parseDate(dateStr, "yyyy-MM-dd HH:mm:ss");
		}catch (Exception ex){
			ex.getStackTrace();
			return null;
		}
	}
	public static String getDateStr(String date) {
		if ("".equals(date)) {
			return "";
		}

		String dateStr = date.substring(0, 4) + "-" + date.substring(4, 6) + "-" + date.substring(6, 8) + " " + date.substring(8, 10) + ":" + date.substring(10, 12) + ":" + date.substring(12, 14);
		return dateStr;

	}
	/**
	 * 对发票明细的数量、单价、不含税单据、不含税金额、税额重新计算
	 * 说明:不要删除或修改入参map的key名称
	 * @param mxItem  spsl\hsdj\bhsdj\hsje\bhsje\se
	 * @param tspz
	 */
	public static void calcItem(CsXxDkdjmx mxItem, String tspz){
		BigDecimal tax= InvoiceCalcUtil.toBigDecimal(StringUtilsExt.getString(mxItem.getTax()),BigDecimal.ZERO);
		String spslStr = StringUtilsExt.getString(mxItem.getSpsl());
		BigDecimal spsl=null;
		if(StringUtils.isNotEmpty(spslStr)){
			spsl=new BigDecimal(spslStr);
		}
		BigDecimal hsdj = mxItem.getHsdj();
		BigDecimal bhsdj =mxItem.getBhsdj();
		BigDecimal hsje = mxItem.getHsje();
		BigDecimal bhsje = mxItem.getBhsje();
		BigDecimal se =mxItem.getTaxje();

		//含税金额为空时，试图通过 数量 单价计算金额
		if(hsje==null||BigDecimal.ZERO.compareTo(hsje)==0){
			if(StringUtils.isNotEmpty(spslStr) && hsdj!=null){
				hsje=spsl.multiply(hsdj).setScale(NumberConstant.NUM_2,RoundingMode.HALF_UP);
			}
		}

		if(bhsje==null||BigDecimal.ZERO.compareTo(bhsje)==0){
			if(StringUtils.isNotEmpty(spslStr) && bhsdj!=null){
				bhsje=spsl.multiply(bhsdj).setScale(NumberConstant.NUM_2,RoundingMode.HALF_UP);
			}
		}

		//如果含税金额 不为空使用含税金额 进行反计算
		if(hsje!=null){
			//数量或单价有为空时重新计算
			if((spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0) ||  (hsdj!=null&&BigDecimal.ZERO.compareTo(hsdj)!=0)){
				if(spsl==null ||BigDecimal.ZERO.compareTo(spsl)==0){
					spsl=InvoiceCalcUtil.calcQuantity(hsje,hsdj);
				} else if(hsdj==null||BigDecimal.ZERO.compareTo(hsdj)==0){
					hsdj=InvoiceCalcUtil.calcPrice(hsje,spsl);
				}
			}

			//计算不含税金额
			if(bhsje==null||BigDecimal.ZERO.compareTo(bhsje)==0){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					bhsje=hsje;
				}
				else {
					if(se!=null&&BigDecimal.ZERO.compareTo(se)!=0){
						bhsje = hsje.subtract(se);
					} else {
						bhsje=InvoiceCalcUtil.calcNoTaxAmount(hsje,tax);
					}
				}
			}

			//税额
			if(se==null){
				se = hsje.subtract(bhsje);
			}

			if((bhsdj==null||BigDecimal.ZERO.compareTo(bhsdj)==0) && (spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0)){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					bhsdj=hsdj;
				}
				else{
					bhsdj=InvoiceCalcUtil.calcPrice(bhsje,spsl);
				}
			}
		} else if(bhsje!=null){
			if((spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0) ||  (bhsdj!=null&&BigDecimal.ZERO.compareTo(bhsdj)!=0)){
				if(spsl==null ||BigDecimal.ZERO.compareTo(spsl)==0){
					spsl=InvoiceCalcUtil.calcQuantity(bhsje,bhsdj);
				} else if(bhsdj==null||BigDecimal.ZERO.compareTo(bhsdj)==0){
					bhsdj=InvoiceCalcUtil.calcPrice(bhsje,spsl);
				}
			}

			//税额
			if(se==null){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					se=BigDecimal.ZERO;
				}
				else {
					se=InvoiceCalcUtil.getValue(bhsje.multiply(tax),2);
				}
			}

			//计算含税金额=不含税金额+税额
			hsje=bhsje.add(se);

			if((hsdj==null||BigDecimal.ZERO.compareTo(hsdj)==0) && (spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0)){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					hsdj=bhsdj;
				}
				else {
					hsdj = InvoiceCalcUtil.calcPrice(hsje,spsl);
				}
			}
		}
		//导入单据不为机动车类型时 对商品数量进行处理
		if (!StringConstant.STR_12.equals(tspz)) {
			if(spsl!=null){
				mxItem.setSpsl(spsl);
			}
		}
		mxItem.setHsdj(hsdj);
		mxItem.setBhsdj(bhsdj);
		mxItem.setHsje(hsje);
		mxItem.setBhsje(bhsje);
		mxItem.setTaxje(se);
	}

	/**
	 * 对发票明细的数量、单价、不含税单据、不含税金额、税额重新计算
	 * 说明:不要删除或修改入参map的key名称
	 * @param mxItem
	 */
	public static void hsBhsConvert(HsBhsConvertVo mxItem){
		BigDecimal tax= InvoiceCalcUtil.toBigDecimal(StringUtilsExt.getString(mxItem.getTax()),BigDecimal.ZERO);
		String spslStr = StringUtilsExt.getString(mxItem.getSpsl());
		BigDecimal spsl=null;
		if(StringUtils.isNotEmpty(spslStr)){
			spsl=new BigDecimal(spslStr);
		}
		BigDecimal hsdj = mxItem.getHsdj();
		BigDecimal bhsdj =mxItem.getBhsdj();
		BigDecimal hsje = mxItem.getHsje();
		BigDecimal bhsje = mxItem.getBhsje();
		BigDecimal se =mxItem.getTaxje();

		//含税金额为空时，试图通过 数量 单价计算金额
		if(hsje==null||BigDecimal.ZERO.compareTo(hsje)==0){
			if(StringUtils.isNotEmpty(spslStr) && hsdj!=null){
				hsje=spsl.multiply(hsdj).setScale(NumberConstant.NUM_2,RoundingMode.HALF_UP);
			}
		}

		if(bhsje==null||BigDecimal.ZERO.compareTo(bhsje)==0){
			if(StringUtils.isNotEmpty(spslStr) && bhsdj!=null){
				bhsje=spsl.multiply(bhsdj).setScale(NumberConstant.NUM_2,RoundingMode.HALF_UP);
			}
		}

		//如果含税金额 不为空使用含税金额 进行反计算
		if(hsje!=null){
			//数量或单价有为空时重新计算
			if((spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0) ||  (hsdj!=null&&BigDecimal.ZERO.compareTo(hsdj)!=0)){
				if(spsl==null ||BigDecimal.ZERO.compareTo(spsl)==0){
					spsl=InvoiceCalcUtil.calcQuantity(hsje,hsdj);
				} else if(hsdj==null||BigDecimal.ZERO.compareTo(hsdj)==0){
					hsdj=InvoiceCalcUtil.calcPrice(hsje,spsl);
				}
			}

			//计算不含税金额
			if(bhsje==null||BigDecimal.ZERO.compareTo(bhsje)==0){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					bhsje=hsje;
				}
				else {
					if(se!=null&&BigDecimal.ZERO.compareTo(se)!=0){
						bhsje = hsje.subtract(se);
					} else {
						bhsje=InvoiceCalcUtil.calcNoTaxAmount(hsje,tax);
					}
				}
			}

			//税额
			if(se==null){
				se = hsje.subtract(bhsje);
			}

			if((bhsdj==null||BigDecimal.ZERO.compareTo(bhsdj)==0) && (spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0)){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					bhsdj=hsdj;
				}
				else{
					bhsdj=InvoiceCalcUtil.calcPrice(bhsje,spsl);
				}
			}
		} else if(bhsje!=null){
			if((spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0) ||  (bhsdj!=null&&BigDecimal.ZERO.compareTo(bhsdj)!=0)){
				if(spsl==null ||BigDecimal.ZERO.compareTo(spsl)==0){
					spsl=InvoiceCalcUtil.calcQuantity(bhsje,bhsdj);
				} else if(bhsdj==null||BigDecimal.ZERO.compareTo(bhsdj)==0){
					bhsdj=InvoiceCalcUtil.calcPrice(bhsje,spsl);
				}
			}

			//税额
			if(se==null){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					se=BigDecimal.ZERO;
				}
				else {
					se=InvoiceCalcUtil.getValue(bhsje.multiply(tax),2);
				}
			}

			//计算含税金额=不含税金额+税额
			hsje=bhsje.add(se);

			if((hsdj==null||BigDecimal.ZERO.compareTo(hsdj)==0) && (spsl!=null&&BigDecimal.ZERO.compareTo(spsl)!=0)){
				if(BigDecimal.ZERO.compareTo(tax)==0){
					hsdj=bhsdj;
				}
				else {
					hsdj = InvoiceCalcUtil.calcPrice(hsje,spsl);
				}
			}
		}
		mxItem.setHsdj(hsdj);
		mxItem.setBhsdj(bhsdj);
		mxItem.setHsje(hsje);
		mxItem.setBhsje(bhsje);
		mxItem.setTaxje(se);
	}

	/**
	 * 对发票明细的数量、单价、不含税单据、不含税金额、税额重新计算(老版)
	 * 说明:不要删除或修改入参map的key名称
	 * @param mxItem  spsl\hsdj\bhsdj\hsje\bhsje\se
	 */
	public static void calcItem(Map mxItem){
		double tax= NumberUtils.toDouble(StringUtilsExt.getString(mxItem.get("tax")));
		String spsl = StringUtilsExt.getString(mxItem.get("spsl"));
		String hsdj = StringUtilsExt.getString(mxItem.get("hsdj"));
		String bhsdj = StringUtilsExt.getString(mxItem.get("bhsdj"));
		String hsje = StringUtilsExt.getString(mxItem.get("hsje"));
		String bhsje = StringUtilsExt.getString(mxItem.get("bhsje"));
		String se = StringUtilsExt.getString(mxItem.get("se"));

		if(StringUtils.isNotEmpty(spsl) && NumberUtils.toDouble(spsl)==0){
			spsl="";
		}

		if(StringUtils.isNotEmpty(hsdj) && NumberUtils.toDouble(hsdj)==0){
			hsdj="";
		}
		if(StringUtils.isNotEmpty(bhsdj) && NumberUtils.toDouble(bhsdj)==0){
			bhsdj="";
		}

		if(StringUtils.isNotEmpty(hsje) && NumberUtils.toDouble(hsje)==0){
			hsje="";
		}
		if(StringUtils.isNotEmpty(bhsje) && NumberUtils.toDouble(bhsje)==0){
			bhsje="";
		}
		if(StringUtils.isNotEmpty(se) && NumberUtils.toDouble(se)==0){
			se="";
		}

		//含税金额为空时，试图通过 数量 单价计算金额
		if(StringUtils.isEmpty(hsje)){
			if(StringUtils.isNotEmpty(spsl) && StringUtils.isNotEmpty(hsdj)){
				hsje=String.valueOf(MathUtils.round(NumberUtils.toDouble(hsdj)*NumberUtils.toDouble(spsl),2));
			}
		}
		if(StringUtils.isEmpty(bhsje)){
			if(StringUtils.isNotEmpty(spsl) && StringUtils.isNotEmpty(bhsdj)){
				bhsje=String.valueOf(MathUtils.round(NumberUtils.toDouble(bhsdj)*NumberUtils.toDouble(spsl),2));
			}
		}

		double tmpHSJE=NumberUtils.toDouble(hsje);
		double tmpBHSJE=NumberUtils.toDouble(bhsje);
		double tmpSE=NumberUtils.toDouble(se);

		//如果含税金额 不为空使用含税金额 进行反计算
		if(StringUtils.isNotEmpty(hsje)){
			//数量或单价有为空时重新计算
			if(StringUtils.isNotEmpty(spsl) || StringUtils.isNotEmpty(hsdj)){
				if(StringUtils.isEmpty(spsl)){
					spsl=String.valueOf(MathUtils.round(tmpHSJE/NumberUtils.toDouble(hsdj),digitLen));
				} else if(StringUtils.isEmpty(hsdj)){
					hsdj=String.valueOf(MathUtils.round(tmpHSJE/NumberUtils.toDouble(spsl),digitLen));
				}
			}

			//计算不含税金额
			if(StringUtils.isEmpty(bhsje)){
				if(tax==0){
					tmpBHSJE=tmpHSJE;
				}
				else {
					if (StringUtils.isNotEmpty(se)) {
						tmpBHSJE = MathUtils.round(tmpHSJE - tmpSE, 2);
					} else {
						tmpBHSJE = MathUtils.round(tmpHSJE / (1 + tax), 2);
					}
				}
			}

			//税额
			if(StringUtils.isEmpty(se)){
				tmpSE=MathUtils.round(tmpHSJE-tmpBHSJE,2);
			}

			if(StringUtils.isEmpty(bhsdj) && StringUtils.isNotEmpty(spsl)){
				if(tax==0){
					bhsdj=hsdj;
				}
				else{
					bhsdj=String.valueOf(MathUtils.round(tmpHSJE / (1 + tax)/NumberUtils.toDouble(spsl),digitLen));
				}

			}
		} else if(StringUtils.isNotEmpty(bhsje)){
			if(StringUtils.isNotEmpty(spsl) || StringUtils.isNotEmpty(bhsdj)){
				if(StringUtils.isEmpty(spsl)){
					spsl=String.valueOf(MathUtils.round(tmpBHSJE/NumberUtils.toDouble(bhsdj),digitLen));
				} else if(StringUtils.isEmpty(bhsdj)){
					bhsdj=String.valueOf(MathUtils.round(tmpBHSJE/NumberUtils.toDouble(spsl),digitLen));
				}
			}

			//税额
			if(StringUtils.isEmpty(se)){
				if(tax==0){
					tmpSE=0.00d;
				} else {
					tmpSE = MathUtils.round(tmpBHSJE * tax, 2);
				}
			}

			//计算含税金额
			tmpHSJE=MathUtils.round(tmpBHSJE+tmpSE,2);

			if(StringUtils.isEmpty(hsdj) && StringUtils.isNotEmpty(spsl)){
				if(tax==0){
					hsdj=bhsdj;
				}
				else {
					hsdj = String.valueOf(MathUtils.round(tmpBHSJE * (1 + tax) / NumberUtils.toDouble(spsl), digitLen));
				}
			}
		}
		//导入单据不为机动车类型时 对商品数量进行处理
		if (!StringUtils.equals("12",StringUtilsExt.getString(mxItem.get("tspz")))) {
			mxItem.put("spsl", handleDecimal(spsl));
		}
		mxItem.put("hsdj", handleDecimal(hsdj));
		mxItem.put("bhsdj", handleDecimal(bhsdj));
		mxItem.put("hsje", tmpHSJE);
		mxItem.put("bhsje", tmpBHSJE);
		mxItem.put("se", tmpSE);
	}

	/**
	 * 负数发票金额、折扣等处理
	 * @param invoiceParam
	 * @return
	 */
	public static InvoiceParam invoiceInfoDiscountProcess(InvoiceParam invoiceParam ){
		//金额变负数
		invoiceParam.setHjje(invoiceParam.getHjje().negate());
		invoiceParam.setHjse(invoiceParam.getHjse().negate());

		List<InvoicemxParam> mxList = invoiceParam.getFpmxs();
		Iterator<InvoicemxParam> it = mxList.iterator();
		while (it.hasNext()){
			InvoicemxParam invoicemxParam = it.next();
			InvoicemxParam nextInvoicemxParam = null;

			String fphxz = invoicemxParam.getFphxz();
			//排除汇总行
			if(!"0".equals(fphxz)&&!"3".equals(fphxz)) {
				//如果为折扣行时跳过
				if("1".equals(fphxz)) {
					continue;
				}

				//获取下一行明细
				if (it.hasNext()) {
					nextInvoicemxParam = it.next();
				}
			}

			if(FphxzEnum.ZCH.getValue().equals(fphxz)){
				//正常行
				invoicemxParam.setSpsl(invoicemxParam.getSpsl().negate());
				invoicemxParam.setHsje(invoicemxParam.getHsje().negate());
				invoicemxParam.setBhsje(invoicemxParam.getBhsje().negate());
				invoicemxParam.setTaxje(invoicemxParam.getTaxje().negate());
			} else if(FphxzEnum.BZKH.getValue().equals(fphxz)) {
				//被折扣行处理
				BigDecimal bhsje = MathUtil.add(invoicemxParam.getBhsje(),nextInvoicemxParam.getBhsje());
				BigDecimal hsje = MathUtil.add(invoicemxParam.getHsje(),nextInvoicemxParam.getHsje());
				//被折扣金额+折扣行金额为0时行数据不显示
				if(bhsje.compareTo(new BigDecimal("0")) == 0) {
					//删除折扣行( 被折扣行待删除)
					invoicemxParam.setBhsje(new BigDecimal("0"));//标志当前行的金额为0(后边要删除)
					invoicemxParam.setHsje(new BigDecimal("0"));//标志当前行的金额为0(后边要删除)
					it.remove();
					continue;
				}
				//含税金额、不含税金额、税额，分别用被折扣的值与折扣行相加，然后取负值。
				invoicemxParam.setBhsje(bhsje.negate());
				invoicemxParam.setHsje(hsje.negate());
				invoicemxParam.setTaxje(MathUtil.add(invoicemxParam.getTaxje(),nextInvoicemxParam.getTaxje()).negate());

				BigDecimal spsl = invoicemxParam.getSpsl();
				if(spsl != null && spsl.compareTo(new BigDecimal("0"))!=0){
					invoicemxParam.setSpsl(spsl.negate());
					//重新计算单价
					invoicemxParam.setBhsdj(bhsje.divide(spsl,2 ,BigDecimal.ROUND_HALF_UP));
					invoicemxParam.setHsdj(hsje.divide(spsl,2 ,BigDecimal.ROUND_HALF_UP));
				}
				//删除折扣行
				it.remove();
			}
		}
		//删除金额为0的行
		it = mxList.iterator();
		int mxhh = 1;
		while (it.hasNext()) {
			InvoicemxParam invoicemxParam = it.next();
			if(invoicemxParam.getBhsje().compareTo(new BigDecimal("0")) == 0){
				it.remove();
			}
			//设为正常行
			invoicemxParam.setFphxz(FphxzEnum.ZCH.getValue());
			invoicemxParam.setMxhh(mxhh);//明细行号
			mxhh ++;
		}

		return invoiceParam;
	}
	/**
	 * 发票查询数据XML标准格式的折扣行处理
	 * @param map
	 * @return
	 */
	public static Map invoiceInfoDiscountProcess(Map map,String fplxdm){
		Map tmpMap=(Map)map.get("kpxx");
		tmpMap=(Map)tmpMap.get("group");
		String qdbz=StringUtilsExt.getString(tmpMap.get("qdbz"));
		if("00000000000000000000".equals(tmpMap.get("ghdwsbh"))){
			tmpMap.put("ghdwsbh","");
		}

		tmpMap.put("hjje",-MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(tmpMap.get("hjje"))),2));
		if(NumberUtils.toDouble(StringUtilsExt.getString(tmpMap.get("hjse")))!=0){
			tmpMap.put("hjse",-MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(tmpMap.get("hjse"))),2));
		}
		else{
			tmpMap.put("hjse","0.00");
		}

		tmpMap.put("jshj",-MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(tmpMap.get("jshj"))),2));

		//费用项目
		tmpMap=(Map)tmpMap.get("fyxm");

/*        if("0".equals(qdbz)){
            tmpMap=(Map)tmpMap.get("fyxm");
        }
        else{
            tmpMap=(Map)tmpMap.get("qdxm");
        }*/

		Object tmpObj= tmpMap.get("group");
		if(tmpObj instanceof ArrayList){
			List<Map> arrList=(ArrayList<Map>)tmpObj;

			Iterator<Map> iterator=arrList.iterator();

			while(iterator.hasNext()){
				Map itemMap=iterator.next();
				Map nextItemMap=null;
				String fphxz=StringUtilsExt.getString(itemMap.get("fphxz"));

				//排除汇总行
				if(!"0".equals(fphxz)&&!"3".equals(fphxz)) {
					//如果为折扣行时跳过
					if("1".equals(fphxz)) {
						continue;
					}

					//获取下一行明细
					if (iterator.hasNext()) {
						nextItemMap = iterator.next();
					}
				}

				//卷票（明细节点有个别不一样）
				if("025".equals(fplxdm))
				{
					//发票查询报文 含税单价和含税金额有值 ;不含税单价和不含税金额没有值
					String tmpVal=StringUtilsExt.getString(itemMap.get("sl"));
					//正常行
					if("0".equals(fphxz)){
						if(!StringUtils.isEmpty(tmpVal)){
							itemMap.put("sl",-MathUtils.round(NumberUtils.toDouble(tmpVal),8));
						}

						tmpVal=StringUtilsExt.getString(itemMap.get("hsje"));
						itemMap.put("hsje",-MathUtils.round(NumberUtils.toDouble(tmpVal),2));

						tmpVal=StringUtilsExt.getString(itemMap.get("bhsje"));
						itemMap.put("bhsje",-MathUtils.round(NumberUtils.toDouble(tmpVal),2));

						tmpVal=StringUtilsExt.getString(itemMap.get("se"));
						if(NumberUtils.toDouble(tmpVal)!=0){
							itemMap.put("se",-MathUtils.round(NumberUtils.toDouble(tmpVal),2));
						}else{
							itemMap.put("se","0.00");
						}
					}
					else if("2".equals(fphxz)){
						//被折扣行金额
						tmpVal=StringUtilsExt.getString(itemMap.get("hsje"));
						Double je=NumberUtils.toDouble(tmpVal,0);

						//折扣行金额
						Double nextJe=NumberUtils.toDouble(StringUtilsExt.getString(nextItemMap.get("hsje")));

						je=MathUtils.round(je+nextJe,2);
						//金额为0时行数据不显示
						if(je==0){
							//删除折扣行（被折扣行还没有删除）
							//标志当前行的金额为0(后边要删除)
							itemMap.put("hsje",0);
							iterator.remove();
							continue;
						}
						itemMap.put("hsje",-MathUtils.round(je,2));

						//税额
						tmpVal=StringUtilsExt.getString(itemMap.get("se"));
						Double se=NumberUtils.toDouble(tmpVal);
						Double nextSe=NumberUtils.toDouble(StringUtilsExt.getString(nextItemMap.get("se")));
						Double tmpSE=MathUtils.round(se+nextSe,2);

						if(tmpSE!=0){
							itemMap.put("se",-tmpSE);
						}else{
							itemMap.put("se","0.00");
						}

						itemMap.put("bhsje",-MathUtils.round(je-tmpSE,2));

						tmpVal=StringUtilsExt.getString(itemMap.get("sl"));
						if(!StringUtils.isEmpty(tmpVal)&&NumberUtils.toDouble(tmpVal)!=0){
							itemMap.put("sl",-MathUtils.round(NumberUtils.toDouble(tmpVal),8));

							//由于金额变了，所以单价也需要重新计算
							itemMap.put("hsdj",MathUtils.round(je/Double.parseDouble(tmpVal),8));
						}
						//删除折扣行
						iterator.remove();
					}
				}
				else{
					//专票、普票
					String tmpVal=StringUtilsExt.getString(itemMap.get("spsl"));
					//正常行
					if("0".equals(fphxz)){
						if(!StringUtils.isEmpty(tmpVal)){
							itemMap.put("spsl",-MathUtils.round(NumberUtils.toDouble(tmpVal),8));
						}
						tmpVal=StringUtilsExt.getString(itemMap.get("je"));
						itemMap.put("je",-MathUtils.round(NumberUtils.toDouble(tmpVal),2));

						tmpVal=StringUtilsExt.getString(itemMap.get("se"));

						if(NumberUtils.toDouble(tmpVal)!=0){
							itemMap.put("se",-MathUtils.round(NumberUtils.toDouble(tmpVal),2));
						}else{
							itemMap.put("se","0.00");
						}

					}
					else if("2".equals(fphxz)){
						//被折扣行金额
						tmpVal=StringUtilsExt.getString(itemMap.get("je"));
						Double je=NumberUtils.toDouble(tmpVal,0);
						//折扣行金额
						Double nextJe=NumberUtils.toDouble(StringUtilsExt.getString(nextItemMap.get("je")));

						je=MathUtils.round(je+nextJe,2);
						//金额为0时行数据不显示
						if(je==0){
							//删除折扣行（被折扣行还没有删除）
							//标志当前行的金额为0(后边要删除)
							itemMap.put("je",0);
							iterator.remove();
							continue;
						}
						itemMap.put("je",-MathUtils.round(je,2));

						//税额
						tmpVal=StringUtilsExt.getString(itemMap.get("se"));
						Double se=NumberUtils.toDouble(tmpVal);
						Double nextSe=NumberUtils.toDouble(StringUtilsExt.getString(nextItemMap.get("se")));

						if(MathUtils.round(se+nextSe,2)!=0){
							itemMap.put("se",-MathUtils.round(se+nextSe,2));
						}else{
							itemMap.put("se","0.00");
						}

						tmpVal=StringUtilsExt.getString(itemMap.get("spsl"));
						if(!StringUtils.isEmpty(tmpVal)&&NumberUtils.toDouble(tmpVal)!=0){
							itemMap.put("spsl",-MathUtils.round(NumberUtils.toDouble(tmpVal),8));
							//由于金额变了，所以单价也需要重新计算
							itemMap.put("dj",MathUtils.round(je/Double.parseDouble(tmpVal),8));
						}
						//删除折扣行
						iterator.remove();
					}
				}
			}

			//移动金额为0的明细行
			iterator=arrList.iterator();
			while(iterator.hasNext()){
				Map item=iterator.next();
				//卷票（明细节点有个别不一样）
				if("025".equals(fplxdm)) {
					if (NumberUtils.toDouble(StringUtilsExt.getString(item.get("hsje"))) == 0) {
						iterator.remove();
					}
				}
				else{
					if (NumberUtils.toDouble(StringUtilsExt.getString(item.get("je"))) == 0) {
						iterator.remove();
					}
				}
			}
		}
		else {
			//(不含税卷票)专票、普票有 详见销货清单 处理
			Map itemMap = (Map) tmpObj;

			String fphxz = StringUtilsExt.getString(itemMap.get("fphxz"));

			//卷票（明细节点有个别不一样）
			if("025".equals(fplxdm)) {
				String tmpVal = StringUtilsExt.getString(itemMap.get("sl"));

				if (!StringUtils.isEmpty(tmpVal)) {
					itemMap.put("sl", -MathUtils.round(NumberUtils.toDouble(tmpVal), 8));
				}

				tmpVal = StringUtilsExt.getString(itemMap.get("hsje"));
				itemMap.put("hsje", -MathUtils.round(NumberUtils.toDouble(tmpVal), 2));

				tmpVal = StringUtilsExt.getString(itemMap.get("bhsje"));
				itemMap.put("bhsje", -MathUtils.round(NumberUtils.toDouble(tmpVal), 2));

				tmpVal = StringUtilsExt.getString(itemMap.get("se"));

				if(MathUtils.round(NumberUtils.toDouble(tmpVal), 2)!=0){
					itemMap.put("se", -MathUtils.round(NumberUtils.toDouble(tmpVal), 2));
				}else{
					itemMap.put("se","0.00");
				}
			}else{
				String tmpVal = StringUtilsExt.getString(itemMap.get("spsl"));

				if (!StringUtils.isEmpty(tmpVal)) {
					itemMap.put("spsl", -MathUtils.round(NumberUtils.toDouble(tmpVal), 8));
				}

				tmpVal = StringUtilsExt.getString(itemMap.get("je"));
				itemMap.put("je", -MathUtils.round(NumberUtils.toDouble(tmpVal), 2));

				tmpVal = StringUtilsExt.getString(itemMap.get("se"));

				if(MathUtils.round(NumberUtils.toDouble(tmpVal), 2)!=0){
					itemMap.put("se", -MathUtils.round(NumberUtils.toDouble(tmpVal), 2));
				}else{
					itemMap.put("se","0.00");
				}
			}
		}

		return map;
	}

	/**
	 * 开票明细项税收编码纠正
	 * @param jsonObject
	 */
	public static void invoiceItemCorrect(JSONObject jsonObject){
		JSONArray itemArrays=jsonObject.getJSONArray("items");

		for(int i=0;i<itemArrays.size();i++){

			JSONObject mxItem = itemArrays.getJSONObject(i);
            //销货清单发票不验证税收编码
            String spmc=mxItem.getString("spmc");
            if(spmc.contains("（详见销货清单）") || spmc.contains("（详见对应正数发票及清单）")){
                continue;
            }
			if(spmc.contains("详见销货清单") || spmc.contains("详见对应正数发票及清单")){
				continue;
			}

			double tax=NumberUtils.toDouble(StringUtils.trimToEmpty(mxItem.getString("tax")),0);
			String mslx=StringUtils.trimToEmpty(mxItem.getString("mslx"));
			String syyhzc=StringUtils.trimToEmpty(mxItem.getString("syyhzc"));
			String yhzc=StringUtils.trimToEmpty(mxItem.getString("yhzc"));

			if(tax>0){
				//正常税率
				mslx="";
			}
			else{
				if("".equals(mslx)){
					//普通零税率
					mslx="3";
				}
			}
			String ssbm=mxItem.getString("ssbm").substring(0,1);
			if(!"6".equals(ssbm)){
				if("".equals(syyhzc)|| "0".equals(syyhzc)){
					yhzc="";
				}else if("1".equals(syyhzc) && "".equals(yhzc)){
					syyhzc="0";
					yhzc="";
				}
			}
			mxItem.put("mslx",mslx);
			mxItem.put("syyhzc",syyhzc);
			mxItem.put("yhzc",yhzc);
		}
	}


	/**
	 * 根据含税金额、税率计算不含税金额
	 * @param hsje
	 * @param tax
	 * @return
	 */
	public static double calcBHSJE(double hsje,double tax){
		if(tax==0){
			return MathUtils.round(hsje,2);
		}
		else{
			return MathUtils.round(hsje/(1+tax),2);
		}
	}
	public static double calcSE(double hsje,double bhsje) {
		return MathUtils.round(hsje - bhsje, 2);
	}


    /**
     * 将明细数据转换成保存单据明细的数据(带明细折扣的处理)
     * @param orderDetailList
     * @param sqdid
     * @return
     */
    public static List getOrderDetailListByDetailDiscount(List orderDetailList,String sqdid) {
        return getOrderDetailListByDetailDiscount(orderDetailList,sqdid,"");
    }

    /**
     * 同步开票接口-机动车API数据转申请单数据
     * @param orderMap
     * @return
     */
    public static  Map getVehicleApplyOrderByApiVehicleData(Map orderMap){
        Map dataMap=new HashMap();
        dataMap.put("bmdm",orderMap.get("bmdm"));
        dataMap.put("gsdm",orderMap.get("gsdm"));
        dataMap.put("user_code",orderMap.get("yhdm"));
        dataMap.put("kplx",orderMap.get("kplx"));
        dataMap.put("sjlx",orderMap.get("sjlx"));
        dataMap.put("sjly",orderMap.get("sjly"));
        dataMap.put("clfs",orderMap.get("clfs"));
        dataMap.put("djbh",orderMap.get("djbh"));
        dataMap.put("djrq",orderMap.get("djrq"));
        dataMap.put("khmc",orderMap.get("khmc"));
        dataMap.put("khsfzh",orderMap.get("khsfzh"));
        dataMap.put("khsh",orderMap.get("khsh"));
        dataMap.put("kpddm",orderMap.get("kpzddm"));
        dataMap.put("cllx",orderMap.get("cllx"));
        dataMap.put("cpxh",orderMap.get("cpxh"));
        dataMap.put("cd",orderMap.get("cd"));
        dataMap.put("cjh",orderMap.get("cjh"));
        dataMap.put("fdjhm",orderMap.get("fdjhm"));
        dataMap.put("scqymc",orderMap.get("scqymc"));
        dataMap.put("sjdh",orderMap.get("sjdh"));
        dataMap.put("jkzmsh",orderMap.get("jkzmsh"));
        dataMap.put("hgzh",orderMap.get("hgzh"));
        dataMap.put("wspzhm",orderMap.get("wspzhm"));
        dataMap.put("dw",orderMap.get("dw"));
        dataMap.put("xcrs",orderMap.get("xcrs"));
        dataMap.put("spfl",orderMap.get("spfl"));
        //dataMap.put("xhfmc",orderMap.get("xhfmc"));
        dataMap.put("xhfdh",orderMap.get("xfdh"));
        dataMap.put("xhfsbh",orderMap.get("xfsh"));
        dataMap.put("xhfzh",orderMap.get("xfzh"));
        dataMap.put("xhfdz",orderMap.get("xfdz"));
        dataMap.put("xhfkhyh",orderMap.get("xfkhyh"));
        dataMap.put("zdkpbz",orderMap.get("zdkpbz"));
        dataMap.put("lockFlag","0");
        dataMap.put("bz",orderMap.get("bz"));
        dataMap.put("fplxdm",orderMap.get("fplxdm"));
        dataMap.put("ssbm",orderMap.get("ssbm"));
        dataMap.put("yhzcbs",orderMap.get("yhzcbs"));
        dataMap.put("lslbs",orderMap.get("lslbs"));
        dataMap.put("zzstsgl",orderMap.get("zzstsgl"));
        dataMap.put("kz1",orderMap.get("kz1"));
        dataMap.put("kz2",orderMap.get("kz2"));
        dataMap.put("kz3",orderMap.get("kz3"));
        dataMap.put("kpr",orderMap.get("kpr"));

        dataMap.put("zdr",orderMap.get("zdr"));
        dataMap.put("khdh",orderMap.get("khdh"));
        dataMap.put("khdz",orderMap.get("khdz"));

        dataMap.put("hsje",orderMap.get("hsje"));
        dataMap.put("tax",orderMap.get("tax"));
        //计算不含税金额 税额
        calcItem(dataMap);

        dataMap.remove("spsl");
        dataMap.remove("hsdj");
        dataMap.remove("bhsdj");
        dataMap.put("bhsj",dataMap.remove("bhsje"));
        dataMap.put("jshj",dataMap.remove("hsje"));

        return dataMap;
    }

    /**
     * 将明细数据转换成保存单据明细的数据(带明细折扣的处理)
     * @param orderDetailList
     * @param sqdid
     * @param djbh
     * @return
     */
    public static List getOrderDetailListByDetailDiscount(List orderDetailList,String sqdid,String djbh) {
        List<Map> list = new ArrayList<>();
        for (int i = 0; i < orderDetailList.size(); i++) {
            Map<String, String> map = (Map) orderDetailList.get(i);

            Map mxItem = new HashMap();

            mxItem.put("sqdid", sqdid);
            mxItem.put("sqdmxid", StringUtilsExt.guidToStr());

            //用于解决明细列表中没有单据编号
            if(StringUtils.isNotEmpty(djbh)) {
                mxItem.put("djbh", djbh);
            }
            else{
                mxItem.put("djbh", StringUtilsExt.getString(map.get("djbh")));
            }

            String djhh=StringUtilsExt.getString(map.get("djhh"));

            //单据行号如果没有自动生成
            if(StringUtils.isEmpty(djhh)){
                mxItem.put("djhh",(i+1));
            }else{
                mxItem.put("djhh",djhh);
            }

            mxItem.put("spmc", StringUtilsExt.getString(map.get("spmc")));
            mxItem.put("spdm", StringUtilsExt.getString(map.get("spdm")));
            mxItem.put("ggxh", StringUtilsExt.getString(map.get("ggxh")));
            mxItem.put("jldw", StringUtilsExt.getString(map.get("jldw")));
            mxItem.put("sppc", StringUtilsExt.getString(map.get("sppc")));
            mxItem.put("spfldm", StringUtilsExt.getString(map.get("spfl")));
            mxItem.put("hbbz", "1");

            mxItem.put("spsl", StringUtilsExt.getString(map.get("spsl")));
            mxItem.put("hsdj", StringUtilsExt.getString(map.get("hsdj")));
            //mxItem.put("hsdj", StringUtilsExt.getString(map.get("spdj")));
            mxItem.put("bhsdj", StringUtilsExt.getString(map.get("bhsdj")));

            //mxItem.put("hsje", StringUtilsExt.getString(map.get("je")));
            mxItem.put("hsje", StringUtilsExt.getString(map.get("hsje")));
            mxItem.put("bhsje", StringUtilsExt.getString(map.get("bhsje")));
            mxItem.put("se", StringUtilsExt.getString(map.get("se")));
            mxItem.put("kz1", StringUtilsExt.getString(map.get("kz1")));
            mxItem.put("kz2", StringUtilsExt.getString(map.get("kz2")));
            mxItem.put("kz3", StringUtilsExt.getString(map.get("kz3")));

            //税率容错处理
            String tax = StringUtilsExt.getString(map.get("tax"));
            if(tax.indexOf("%")>-1){
                tax=tax.replaceAll("%","");
            }
            double tmpTax=NumberUtils.toDouble(tax);

            if(tmpTax>1){
                tax=String.valueOf(MathUtils.round(tmpTax/100,2));
            }
            mxItem.put("tax", tax);

            Double zkje = MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(map.get("zkje"))), 2);
            mxItem.put("zkje", zkje);
            if(zkje == 0){
				mxItem.put("fphxz", '0');//发票行性质 0-正常行  1-折扣行 2-被折扣行
			}else if(zkje !=0){
				mxItem.put("fphxz", '2');//发票行性质 0-正常行  1-折扣行 2-被折扣行
			}

            //明细税收编码容错处理
            mxItem.put("ssbm", StringUtilsExt.getString(map.get("ssbm")));
            String ssbm=StringUtilsExt.getString(mxItem.get("ssbm"));
            if(!"".equals(ssbm)){
                if(ssbm.length()>19){
                    ssbm=ssbm.substring(0,19);
                }else if(ssbm.length()<19){
                    ssbm= StringUtils.rightPad(ssbm,19,'0');
                }
                mxItem.put("ssbm",ssbm);
            }

            mxItem.put("syyhzc", StringUtilsExt.getString(map.get("yhzcbs")));
            mxItem.put("yhzc", StringUtilsExt.getString(map.get("zzstsgl")));
            mxItem.put("mslx", StringUtilsExt.getString(map.get("lslbs")));

            String mslx=StringUtilsExt.getString(mxItem.get("mslx"));
            String syyhzc=StringUtilsExt.getString(mxItem.get("syyhzc"));
            String yhzc=StringUtilsExt.getString(mxItem.get("yhzc"));

            //mslx  空-正常税率  1-免税 2-不征税 3-普通零税率
            if(NumberUtils.toDouble(tax)>0){
                mxItem.put("mslx", "");
                mxItem.put("syyhzc", "0");
                mxItem.put("yhzc", "");
            }else{
                //正常税率时为普通零税率
                if("".equals(mslx)){
                    mxItem.put("mslx","3");
                    mxItem.put("syyhzc", "0");
                    mxItem.put("yhzc", "");
                }else{
                    if("1".equals(syyhzc))
                    {
                        if(StringUtils.isEmpty(yhzc))
                        {
                            mxItem.put("syyhzc", "0");
                            mxItem.put("yhzc", "");
                        }
                    } else{
                        mxItem.put("syyhzc", "0");
                        mxItem.put("yhzc", "");
                    }
                }
            }

            //重进新计算明细项相关金额数据
            FPUtil.calcItem(mxItem);

            //明细添加
            //值添加正数金额的明细行，避免接口返回数据中本身就有折扣行，造成重复增加折扣明细行 2020-6-8 15:47:20 rdd
            double hsjeDou = (double)mxItem.get("hsje");
            if (hsjeDou != 0){
				list.add(mxItem);
			}
            if(hsjeDou > 0){
                //自动增加折扣行
                //折扣金额不为0时
                if (zkje != 0) {
                    Map discountMap = new HashMap<>();

                    discountMap.put("sqdid", sqdid);
                    discountMap.put("sqdmxid", StringUtilsExt.guidToStr());

                    discountMap.put("djbh", StringUtilsExt.getString(mxItem.get("djbh")));
                    discountMap.put("djhh", StringUtilsExt.getString(mxItem.get("djhh")));
                    discountMap.put("spmc", StringUtilsExt.getString(mxItem.get("spmc")));
                    discountMap.put("spdm", StringUtilsExt.getString(mxItem.get("spdm")));
                    discountMap.put("ggxh", "");
                    discountMap.put("jldw", "");
                    discountMap.put("sppc", "");
                    discountMap.put("spfldm", StringUtilsExt.getString(mxItem.get("spfldm")));
                    discountMap.put("hbbz", "0");

                    discountMap.put("ssbm", StringUtilsExt.getString(mxItem.get("ssbm")));
                    discountMap.put("syyhzc", StringUtilsExt.getString(mxItem.get("syyhzc")));
                    discountMap.put("yhzc", StringUtilsExt.getString(mxItem.get("yhzc")));
                    discountMap.put("mslx", StringUtilsExt.getString(mxItem.get("mslx")));

                    discountMap.put("hsje", -MathUtils.round(Math.abs(zkje),2));
                    discountMap.put("tax",tax);

                    if(NumberUtils.toDouble(tax)==0){
                        discountMap.put("bhsje", -Math.abs(zkje));
                        discountMap.put("se", 0);
                    }
                    else{
                        double tmpHJSE=MathUtils.round(Math.abs(zkje),2);
                        double tmpBHSJE=FPUtil.calcBHSJE(tmpHJSE,NumberUtils.toDouble(tax));
                        double tmpSE=tmpHJSE-tmpBHSJE;
                        discountMap.put("bhsje",-tmpBHSJE);
                        discountMap.put("se", -tmpSE);
                    }
					discountMap.put("fphxz","1");//发票行性质 0-正常行  1-折扣行 2-被折扣行
                    list.add(discountMap);
                }
            }
        }
        return list;
    }


    /**
     * 将申请单数据转换成开票信息数据
     * @param orderMap
     * @param orderDetailMap
     * @return
     */
    public static JSONObject getInvoiceByApplyOrder(Map orderMap,List<Map> orderDetailMap) {
        JSONObject orderJson=new JSONObject();
        orderJson.put("sqdid",orderMap.get("sqdid"));
        orderJson.put("djbh",orderMap.get("djbh"));
        orderJson.put("fplxdm",orderMap.get("fplxdm"));
        orderJson.put("zsfs",orderMap.get("zsfs"));
        orderJson.put("kce",orderMap.get("kce"));
        orderJson.put("tspz",orderMap.get("tspz"));

        orderJson.put("gfmc",orderMap.get("khmc"));
        orderJson.put("gfnsrsbh",orderMap.get("khsh"));
        orderJson.put("gfdzdh",orderMap.get("khdzdh"));
        orderJson.put("gfyhzh",orderMap.get("khyhzh"));
        orderJson.put("gflxfs",orderMap.get("khlxfs"));
        orderJson.put("skr",orderMap.get("skr"));
        orderJson.put("fhr",orderMap.get("fhr"));
        orderJson.put("kpr",orderMap.get("kpr"));
        orderJson.put("bz",orderMap.get("bz"));



        orderJson.put("tzdbh",orderMap.get("tzdbh"));
        orderJson.put("yfpdm",orderMap.get("yfpdm"));
        orderJson.put("yfphm",orderMap.get("yfphm"));
		orderJson.put("zsxhdwmc",orderMap.get("zsxhdwmc"));
		orderJson.put("zsxhdwsbh",orderMap.get("zsxhdwsbh"));
		//20221031 支持同一个终端 多个销方地址电话 银行账号
		orderJson.put("xfdzdh",orderMap.get("xfdzdh"));
		orderJson.put("xfyhzh",orderMap.get("xfyhzh"));
        //开票明细
        orderJson.put("items",orderDetailMap);

        //
		//double hjje=0d;
		//double hjse=0d;
		BigDecimal hjje=new BigDecimal(0);
		BigDecimal hjse=new BigDecimal(0);
        for(Map item :orderDetailMap){
			hjje = hjje.add(new BigDecimal(StringUtilsExt.getString(item.get("bhsje"))));
			hjse = hjse.add(new BigDecimal(StringUtilsExt.getString(item.get("se"))));
            //hjje=hjje+NumberUtils.toDouble(StringUtilsExt.getString(item.get("bhsje")));
            //hjse=hjse+NumberUtils.toDouble(StringUtilsExt.getString(item.get("se")));
        }
        //hjje=MathUtils.round(hjje,2);
        //hjse=MathUtils.round(hjse,2);
		hjje = hjje.setScale(2,BigDecimal.ROUND_HALF_UP);
		hjse = hjse.setScale(2,BigDecimal.ROUND_HALF_UP);
        orderJson.put("hjje",hjje);
        orderJson.put("hjse",hjse);
        //此处理使用单据的开票金额，而不使用明细合并的金额，通过 接口判断单据金额与明细合并的金额不一样
		//20220610 兼容用户传递不含税金额
		String hsje = StringUtilsExt.getString(orderMap.get("hsje"));
		String bhsjeStr = StringUtilsExt.getString(orderMap.get("bhsje"));
		//double jshj = 0d;
		BigDecimal jshj=new BigDecimal(0);
		if (!StringUtil.isEmpty(hsje)) {
			//jshj = NumberUtils.toDouble(hsje);
			//jshj = MathUtils.round(jshj, 2);
			jshj = new BigDecimal(hsje);
			jshj = jshj.setScale(2,BigDecimal.ROUND_HALF_UP);
		} else if (!StringUtil.isEmpty(bhsjeStr)) {
			//Double bhsje = NumberUtils.toDouble(bhsjeStr);
			//jshj = MathUtils.round(bhsje, 2) + hjse;
			BigDecimal bhsje = new BigDecimal(bhsjeStr);
			jshj = bhsje.setScale(2,BigDecimal.ROUND_HALF_UP).add(hjse);
		}
		orderJson.put("jshj", jshj);
        /*orderJson.put("gfmc",orderMap.get(""));
        orderJson.put("gfmc",orderMap.get(""));
        orderJson.put("gfmc",orderMap.get(""));
        orderJson.put("gfmc",orderMap.get(""));
        orderJson.put("gfmc",orderMap.get(""));
        orderJson.put("gfmc",orderMap.get(""));
        orderJson.put("gfmc",orderMap.get(""));
        orderJson.put("gfmc",orderMap.get(""));*/
        return orderJson;
    }

    /**
     * 同步开票，接收到的报文转换成开票信息数据
     * @param orderMap
     * @param orderDetailMap
     * @return
     */
    public static JSONObject getInvoiceByAPIData(Map orderMap,List<Map> orderDetailMap) {
        JSONObject orderJson=new JSONObject();
        orderJson.put("fplxdm",orderMap.get("fplxdm"));
        orderJson.put("zsfs",orderMap.get("zsfs"));
        orderJson.put("kce",orderMap.get("kce"));
        orderJson.put("tspz",orderMap.get("tspz"));

        orderJson.put("gfmc",orderMap.get("khmc"));
        orderJson.put("gfnsrsbh",orderMap.get("khsh"));
        orderJson.put("gfdzdh",orderMap.get("khdzdh"));
        orderJson.put("gfyhzh",orderMap.get("khyhzh"));
        orderJson.put("gflxfs",orderMap.get("khlxfs"));
        orderJson.put("skr",orderMap.get("skr"));
        orderJson.put("fhr",orderMap.get("fhr"));
        orderJson.put("kpr",orderMap.get("kpr"));
        orderJson.put("bz",orderMap.get("bz"));

        orderJson.put("tzdbh",orderMap.get("tzdbh"));
        orderJson.put("yfpdm",orderMap.get("yfpdm"));
        orderJson.put("yfphm",orderMap.get("yfphm"));
		orderJson.put("zsxhdwmc",orderMap.get("zsxhdwmc"));
		orderJson.put("zsxhdwsbh",orderMap.get("zsxhdwsbh"));
		orderJson.put("xfdzdh",orderMap.get("xfdzdh"));
		orderJson.put("xfyhzh",orderMap.get("xfyhzh"));
        //开票明细
        orderJson.put("items",orderDetailMap);

        //
        double hjje=0d;
        double hjse=0d;
        for(Map item :orderDetailMap){
            hjje=hjje+NumberUtils.toDouble(StringUtilsExt.getString(item.get("bhsje")));
            hjse=hjse+NumberUtils.toDouble(StringUtilsExt.getString(item.get("se")));
        }
        hjje=MathUtils.round(hjje,2);
        hjse=MathUtils.round(hjse,2);

        orderJson.put("hjje",hjje);
        orderJson.put("hjse",hjse);
        //此处理使用单据的开票金额，而不使用明细合并的金额，通过 接口判断单据金额与明细合并的金额不一样
		//20220610 兼容用户传递不含税金额
		String hsje = StringUtilsExt.getString(orderMap.get("hsje"));
		String bhsjeStr = StringUtilsExt.getString(orderMap.get("bhsje"));
		Double jshj = 0d;
		if (!StringUtil.isEmpty(hsje)) {
			jshj = NumberUtils.toDouble(hsje);
			jshj = MathUtils.round(jshj, 2);
		} else if (!StringUtil.isEmpty(bhsjeStr)) {
			Double bhsje = NumberUtils.toDouble(bhsjeStr);
			jshj = MathUtils.round(bhsje, 2) + hjse;
		}
		orderJson.put("jshj", jshj);
        return orderJson;
    }

    /**
     * 将申请单数据转换成机动车开票数据
     * @param orderMap
     * @return
     */
    public static Map<String,Object> getVehicleInvoiceByApplyOrder(Map orderMap) {
        Map<String,Object> dataMap=new HashMap<>();
        dataMap.put("fplxdm",orderMap.get("005"));
        dataMap.put("bmdm",orderMap.get("bmdm"));
        dataMap.put("kplx",orderMap.get("kplx"));
        dataMap.put("djbh",orderMap.get("djbh"));
        dataMap.put("ghfmc",orderMap.get("khmc"));
        dataMap.put("sfzhm",orderMap.get("khsfzh"));
        dataMap.put("ghfsbh",orderMap.get("khsh"));
        dataMap.put("cllx",orderMap.get("cllx"));
        dataMap.put("cpxh",orderMap.get("cpxh"));
        dataMap.put("cd",orderMap.get("cd"));
        dataMap.put("fdjhm",orderMap.get("fdjhm"));
        dataMap.put("clsbdh",orderMap.get("cjh"));
        dataMap.put("scqymc",orderMap.get("scqymc"));
        dataMap.put("sjdh",orderMap.get("sjdh"));
        dataMap.put("jkzmsh",orderMap.get("jkzmsh"));
        dataMap.put("hgzh",orderMap.get("hgzh"));
        dataMap.put("wspzhm",orderMap.get("wspzhm"));
        dataMap.put("dw",orderMap.get("dw"));
        dataMap.put("xcrs",orderMap.get("xcrs"));
        dataMap.put("dh",orderMap.get("xhfdh"));
        dataMap.put("xhfsbh",orderMap.get("xhfsbh"));
        dataMap.put("zh",orderMap.get("xhfzh"));
        dataMap.put("dz",orderMap.get("xhfdz"));
        dataMap.put("khyh",orderMap.get("xhfkhyh"));
        dataMap.put("bz",orderMap.get("bz"));
        dataMap.put("fplxdm",orderMap.get("fplxdm"));
        dataMap.put("spbm",orderMap.get("ssbm"));
        dataMap.put("yhzcbs",orderMap.get("yhzcbs"));
        dataMap.put("lslbs",orderMap.get("lslbs"));
        dataMap.put("zzstsgl",orderMap.get("zzstsgl"));
        dataMap.put("kpr",orderMap.get("kpr"));
        dataMap.put("jdcpy",orderMap.get("jdcpy"));
        dataMap.put("sl",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(orderMap.get("tax"))),2));
        dataMap.put("bhsj",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(orderMap.get("bhsj"))),2));
        dataMap.put("jshj",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(orderMap.get("jshj"))),2));
        dataMap.put("se",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(orderMap.get("se"))),2));
        return dataMap;
    }


    /**
     * 将机动车API数据转换成机动车开票
     * @param orderMap
     * @return
     */
    public static Map<String,Object> getVehicleInvoiceByAPIData(Map orderMap) {
        Map dataMap=new HashMap();
        dataMap.put("fplxdm","005");
        dataMap.put("kplx",orderMap.get("kplx"));
        dataMap.put("ghfmc",orderMap.get("khmc"));
        dataMap.put("sfzhm",orderMap.get("khsfzh"));
        dataMap.put("ghfsbh",orderMap.get("khsh"));
        dataMap.put("cllx",orderMap.get("cllx"));
        dataMap.put("cpxh",orderMap.get("cpxh"));
        dataMap.put("cd",orderMap.get("cd"));
        dataMap.put("clsbdh",orderMap.get("cjh"));
        dataMap.put("fdjhm",orderMap.get("fdjhm"));
        dataMap.put("scqymc",orderMap.get("scqymc"));
        dataMap.put("sjdh",orderMap.get("sjdh"));
        dataMap.put("jkzmsh",orderMap.get("jkzmsh"));
        dataMap.put("hgzh",orderMap.get("hgzh"));
        dataMap.put("wspzhm",orderMap.get("wspzhm"));
        dataMap.put("dw",orderMap.get("dw"));
        dataMap.put("xcrs",orderMap.get("xcrs"));
        dataMap.put("dh",orderMap.get("xfdh"));
        dataMap.put("xhfsbh",orderMap.get("xfsh"));
        dataMap.put("zh",orderMap.get("xfzh"));
        dataMap.put("dz",orderMap.get("xfdz"));
        dataMap.put("khyh",orderMap.get("xfkhyh"));
        dataMap.put("jdcpy",orderMap.get("jdcpy"));

        dataMap.put("yfpdm",orderMap.get("yfpdm"));
        dataMap.put("yfphm",orderMap.get("yfphm"));

        dataMap.put("bz","一车一票");

        dataMap.put("spbm",orderMap.get("ssbm"));
        dataMap.put("yhzcbs",orderMap.get("yhzcbs"));
        dataMap.put("lslbs",orderMap.get("lslbs"));
        dataMap.put("zzstsgl",orderMap.get("zzstsgl"));

        dataMap.put("kpr",orderMap.get("kpr"));

        dataMap.put("hsje",orderMap.get("je"));
        dataMap.put("tax",orderMap.get("tax"));
        //计算不含税金额 税额
        calcItem(dataMap);

        dataMap.remove("spsl");
        dataMap.remove("hsdj");
        dataMap.remove("bhsdj");
        dataMap.put("bhsj",dataMap.remove("bhsje"));
        dataMap.put("jshj",dataMap.remove("hsje"));
        dataMap.put("sl",dataMap.remove("tax"));

        dataMap.put("bhsj",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(dataMap.get("bhsj"))),2));
        dataMap.put("jshj",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(dataMap.get("jshj"))),2));
        dataMap.put("se",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(dataMap.get("se"))),2));
        dataMap.put("sl",MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(dataMap.get("sl"))),2));
        return dataMap;
    }

	/**
	 * 将接口传入的参数转换成开票的数据
	 * @param orderDetailList
	 * @return
	 */
	public static List getInvoiceDetailListByDetailDiscount(List orderDetailList,Map fpkjMap) {
		String kplx = StringUtilsExt.getString(fpkjMap.get("kplx"));
		List<Map> list = new ArrayList<>();
		for (int i = 0; i < orderDetailList.size(); i++) {
			Map<String, String> map = (Map) orderDetailList.get(i);

			Map mxItem = new HashMap();

			mxItem.put("spmc", StringUtilsExt.getString(map.get("spmc")));
			mxItem.put("ggxh", StringUtilsExt.getString(map.get("ggxh")));
			mxItem.put("dw", StringUtilsExt.getString(map.get("jldw")));
			mxItem.put("hbbz", "1");

			mxItem.put("spsl", StringUtilsExt.getString(map.get("spsl")));
			mxItem.put("hsdj", StringUtilsExt.getString(map.get("hsdj")));
			//mxItem.put("hsdj", StringUtilsExt.getString(map.get("spdj")));
			mxItem.put("bhsdj", StringUtilsExt.getString(map.get("bhsdj")));

			//mxItem.put("hsje", StringUtilsExt.getString(map.get("je")));
			mxItem.put("hsje", StringUtilsExt.getString(map.get("hsje")));
			mxItem.put("bhsje", StringUtilsExt.getString(map.get("bhsje")));
			mxItem.put("se", StringUtilsExt.getString(map.get("se")));

			//税率容错处理
			String tax = StringUtilsExt.getString(map.get("tax"));
			if(tax.indexOf("%")>-1){
				tax=tax.replaceAll("%","");
			}
			double tmpTax=NumberUtils.toDouble(tax);

			if(tmpTax>1){
				tax=String.valueOf(MathUtils.round(tmpTax/100,2));
			}
			mxItem.put("tax", tax);

			Double zkje = MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(map.get("zkje"))), 2);
			mxItem.put("zkje", zkje);

			//明细税收编码容错处理
			mxItem.put("ssbm", StringUtilsExt.getString(map.get("ssbm")));
			String ssbm=StringUtilsExt.getString(mxItem.get("ssbm"));
			if(!"".equals(ssbm)){
				if(ssbm.length()>19){
					ssbm=ssbm.substring(0,19);
				}else if(ssbm.length()<19){
					ssbm= StringUtils.rightPad(ssbm,19,'0');
				}
				mxItem.put("ssbm",ssbm);
			}

			mxItem.put("syyhzc", StringUtilsExt.getString(map.get("yhzcbs")));
			mxItem.put("yhzc", StringUtilsExt.getString(map.get("zzstsgl")));
			mxItem.put("mslx", StringUtilsExt.getString(map.get("lslbs")));

			String mslx=StringUtilsExt.getString(mxItem.get("mslx"));
			String syyhzc=StringUtilsExt.getString(mxItem.get("syyhzc"));
			String yhzc=StringUtilsExt.getString(mxItem.get("yhzc"));

			//mslx  空-正常税率  1-免税 2-不征税 3-普通零税率
			if(NumberUtils.toDouble(tax)>0){
				mxItem.put("mslx", "");
				mxItem.put("syyhzc", "0");
				mxItem.put("yhzc", "");
			}else{
				//正常税率时为普通零税率
				if(StringUtils.isEmpty(mslx)){
					mxItem.put("mslx","3");
					mxItem.put("syyhzc", "0");
					mxItem.put("yhzc", "");
				}else{
					if("1".equals(syyhzc))
					{
						if(StringUtils.isEmpty(yhzc))
						{
							mxItem.put("syyhzc", "0");
							mxItem.put("yhzc", "");
						}
					} else{
						mxItem.put("syyhzc", "0");
						mxItem.put("yhzc", "");
					}
				}
			}
			//差额征税 补全
			if ("2".equals(fpkjMap.get("zsfs"))){
				FPUtil.calcMxForCezs(mxItem, StringUtilsExt.getString(fpkjMap.get("kce"),"0"));
			} else {
				FPUtil.calcItem(mxItem);
			}

			list.add(mxItem);

			//明细添加
			//负数发票时不需要折扣处理
			if(!"1".equals(kplx)){
				//自动增加折扣行
				//折扣金额不为0时
				if (zkje != 0) {
					Map discountMap = new HashMap<>();

					discountMap.put("spmc", StringUtilsExt.getString(mxItem.get("spmc")));
					discountMap.put("spdm", StringUtilsExt.getString(mxItem.get("spdm")));
					discountMap.put("ggxh", "");
					discountMap.put("jldw", "");
					discountMap.put("sppc", "");
					discountMap.put("ssbm", StringUtilsExt.getString(mxItem.get("ssbm")));
					discountMap.put("syyhzc", StringUtilsExt.getString(mxItem.get("syyhzc")));
					discountMap.put("yhzc", StringUtilsExt.getString(mxItem.get("yhzc")));
					discountMap.put("mslx", StringUtilsExt.getString(mxItem.get("mslx")));

					discountMap.put("hsje", -MathUtils.round(Math.abs(zkje),2));
					discountMap.put("tax",tax);

					if(NumberUtils.toDouble(tax)==0){
						discountMap.put("bhsje", -Math.abs(zkje));
						discountMap.put("se", 0);
					}
					else{
						double tmpHJSE=MathUtils.round(Math.abs(zkje),2);
						double tmpBHSJE=FPUtil.calcBHSJE(tmpHJSE,NumberUtils.toDouble(tax));
						double tmpSE=tmpHJSE-tmpBHSJE;
						discountMap.put("bhsje",-tmpBHSJE);
						discountMap.put("se", -tmpSE);
					}

					list.add(discountMap);
				}
			}
		}
		return list;
	}

	/**
	 * 根据计算公式“税额=（含税销售额-扣除额）X税率或征收率/（1+税率或征收率）”计算出税额，根据“金额=含税销售额-税额”计算出金额，
	 * 如果此时“数量”内容已填写，则根据“金额”的值计算出“单价”
	 * @author chb
	 * @param mxItem
	 * @param kceStr
	 */
	public static void calcMxForCezs(Map mxItem, String kceStr){
		BigDecimal tax = new BigDecimal(StringUtilsExt.getString(mxItem.get("tax"), "0"));
		BigDecimal spsl = new BigDecimal(StringUtilsExt.getString(mxItem.get("spsl"), "0"));
		BigDecimal hsdj = new BigDecimal(StringUtilsExt.getString(mxItem.get("hsdj"), "0"));
		BigDecimal bhsdj = new BigDecimal(StringUtilsExt.getString(mxItem.get("bhsdj"), "0"));
		BigDecimal hsje = new BigDecimal(StringUtilsExt.getString(mxItem.get("hsje"), "0"));
		BigDecimal bhsje = new BigDecimal(StringUtilsExt.getString(mxItem.get("bhsje"), "0"));
		BigDecimal se = new BigDecimal(StringUtilsExt.getString(mxItem.get("se"), "0"));
		BigDecimal kce = new BigDecimal(kceStr);

		if (se.doubleValue() == 0.0) {
			se = hsje.subtract(kce).multiply(tax).divide(tax.add(new BigDecimal(1)), CustomConst.JE_SCALE, RoundingMode.HALF_UP);
		}
		if (bhsje.doubleValue() == 0.0) {
			bhsje = hsje.subtract(se).setScale(CustomConst.JE_SCALE, RoundingMode.HALF_UP);
		}
		if (hsdj.doubleValue() == 0.0 && spsl.doubleValue()!=0.0) {
			hsdj = hsje.divide(spsl, CustomConst.JG_SCALE, RoundingMode.HALF_UP);
		}
		if (bhsdj.doubleValue() == 0.0 && spsl.doubleValue()!=0.0) {
			bhsdj = bhsje.divide(spsl, CustomConst.JG_SCALE, RoundingMode.HALF_UP);
		}
		if (spsl.doubleValue() == 0.0 && hsdj.doubleValue()!=0.0) {
			spsl = hsje.divide(hsdj, CustomConst.JG_SCALE, RoundingMode.HALF_UP);
		}

		mxItem.put("spsl",spsl.toPlainString());
		mxItem.put("hsdj",hsdj.toPlainString());
		mxItem.put("bhsdj",bhsdj.toPlainString());
		mxItem.put("hsje",hsje.doubleValue());
		mxItem.put("bhsje",bhsje.doubleValue());
		mxItem.put("se",se.doubleValue());
	}

    public  static List getOrderDetailListByOrderDiscount(List fpsqdglMxList,String sqdid,Double discountAmount) {
        List<Map> list = new ArrayList<>();
        for (int i = 0; i < fpsqdglMxList.size(); i++) {
            Map<String, String> map = (Map) fpsqdglMxList.get(i);
            Map mxItem = new HashMap();

            mxItem.put("sqdid", sqdid);
            mxItem.put("sqdmxid", StringUtilsExt.guidToStr());

            mxItem.put("djbh", StringUtilsExt.getString(map.get("djbh")));
            mxItem.put("djhh", StringUtilsExt.getString(map.get("djhh")));
            mxItem.put("spmc", StringUtilsExt.getString(map.get("spmc")));
            mxItem.put("spdm", StringUtilsExt.getString(map.get("spdm")));
            mxItem.put("ggxh", StringUtilsExt.getString(map.get("ggxh")));
            mxItem.put("jldw", StringUtilsExt.getString(map.get("jldw")));
            mxItem.put("sppc", StringUtilsExt.getString(map.get("sppc")));
            mxItem.put("spfldm", StringUtilsExt.getString(map.get("spfl")));
            mxItem.put("hbbz", "0");

            mxItem.put("spsl", StringUtilsExt.getString(map.get("spsl")));
            mxItem.put("hsdj", StringUtilsExt.getString(map.get("spdj")));
            //mxItem.put("hsdj", StringUtilsExt.getString(map.get("spdj")));
            mxItem.put("bhsdj", "");

            mxItem.put("hsje", StringUtilsExt.getString(map.get("je")));
            mxItem.put("bhsje", "");
            mxItem.put("tax", StringUtilsExt.getString(map.get("tax")));
            mxItem.put("se", "");

            Double zkje = MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(map.get("zkje"))), 2);
            mxItem.put("zkje", zkje);

            //
            mxItem.put("ssbm", StringUtilsExt.getString(map.get("ssbm")));
            String ssbm=StringUtilsExt.getString(mxItem.get("ssbm"));
            if(ssbm.length()>19){
                ssbm=ssbm.substring(0,19);
            }else if(ssbm.length()<19){
                ssbm= StringUtils.rightPad(ssbm,19,'0');
            }
            mxItem.put("ssbm",ssbm);

            mxItem.put("syyhzc", StringUtilsExt.getString(map.get("yhzcbs")));
            mxItem.put("yhzc", StringUtilsExt.getString(map.get("zzstsgl")));
            mxItem.put("mslx", StringUtilsExt.getString(map.get("lslbs")));

            String mslx=StringUtilsExt.getString(mxItem.get("mslx"));
            String syyhzc=StringUtilsExt.getString(mxItem.get("syyhzc"));
            String yhzc=StringUtilsExt.getString(mxItem.get("yhzc"));

            String tax = StringUtilsExt.getString(mxItem.get("tax"));

            //mslx  空-正常税率  1-免税 2-不征税 3-普通零税率
            if(NumberUtils.toDouble(tax)>0){
                mxItem.put("mslx", "");
                mxItem.put("syyhzc", "0");
                mxItem.put("yhzc", "");
            }else{
                //正常税率时为普通零税率
                if("".equals(mslx)){
                    mxItem.put("mslx","3");
                    mxItem.put("syyhzc", "0");
                    mxItem.put("yhzc", "");
                }else{
                    if("1".equals(syyhzc))
                    {
                        if(StringUtils.isEmpty(yhzc))
                        {
                            mxItem.put("syyhzc", "0");
                            mxItem.put("yhzc", "");
                        }
                    } else{
                        mxItem.put("syyhzc", "0");
                        mxItem.put("yhzc", "");
                    }
                }
            }

            //对单价、税额、金额进行计算
            Map<String, String> mapTaxCalculated = taxCalculated(String.valueOf(mxItem.get("hsje")), tax);

            mxItem.put("bhsje", mapTaxCalculated.get("bhsje"));
            mxItem.put("se", mapTaxCalculated.get("se"));

            String spsl = StringUtilsExt.getString(mxItem.get("spsl"));
            String hsdj = StringUtilsExt.getString(mxItem.get("hsdj"));

            Double tmpHSJE = MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(mxItem.get("hsje"))), 2);
            Double tmpBHSJE = MathUtils.round(NumberUtils.toDouble(StringUtilsExt.getString(mxItem.get("bhsje"))), 2);

            if (!StringUtils.isEmpty(spsl) && NumberUtils.toDouble(spsl) != 0) {
                Double tmpSPSL = MathUtils.round(NumberUtils.toDouble(spsl), digitLen);
                mxItem.put("spsl", tmpSPSL);

                //如果价格单价为空 重新计算
                if (StringUtils.isEmpty(hsdj)) {
                    mxItem.put("hsdj", MathUtils.round(Math.abs(tmpHSJE) / Math.abs(tmpSPSL), digitLen));
                }

                //税率为0时 含税与不含税一样
                if (NumberUtils.toDouble(tax) == 0) {
                    mxItem.put("bhsdj", mxItem.get("hsdj"));
                } else {
                    Double tmpBHSDJ = MathUtils.round(tmpBHSJE / tmpSPSL, digitLen);
                    mxItem.put("bhsdj", tmpBHSDJ);
                }
            } else if (!StringUtils.isEmpty(hsdj) && NumberUtils.toDouble(hsdj) != 0) {
                Double tmpHSDJ = MathUtils.round(NumberUtils.toDouble(hsdj), digitLen);

                mxItem.put("hsdj", tmpHSDJ);
                Double tmpSPSL = MathUtils.round(tmpHSJE / tmpHSDJ, digitLen);

                mxItem.put("spsl", tmpSPSL);

                //税率为0时 含税与不含税一样
                if (NumberUtils.toDouble(tax) == 0) {
                    mxItem.put("bhsdj", tmpHSDJ);
                } else {
                    Double tmpBHSDJ = MathUtils.round(tmpBHSJE / tmpSPSL, digitLen);
                    mxItem.put("bhsdj", tmpBHSDJ);
                }
            } else {
                mxItem.put("bhsdj", "");
                mxItem.put("hsdj", "");
                mxItem.put("spsl", "");
            }
            //明细添加
            list.add(mxItem);

            //自动增加折扣行
            //折扣金额不为0时
            if (zkje != 0) {
                Map discountMap = new HashMap<>();

                discountMap.put("sqdid", sqdid);
                discountMap.put("sqdmxid", StringUtilsExt.guidToStr());

                discountMap.put("djbh", StringUtilsExt.getString(mxItem.get("djbh")));
                discountMap.put("djhh", StringUtilsExt.getString(mxItem.get("djhh")));
                discountMap.put("spmc", StringUtilsExt.getString(mxItem.get("spmc")));
                discountMap.put("spdm", StringUtilsExt.getString(mxItem.get("spdm")));
                discountMap.put("ggxh", "");
                discountMap.put("jldw", "");
                discountMap.put("sppc", "");
                discountMap.put("spfldm", StringUtilsExt.getString(mxItem.get("spfldm")));
                discountMap.put("hbbz", "0");

                discountMap.put("ssbm", StringUtilsExt.getString(mxItem.get("ssbm")));
                discountMap.put("syyhzc", StringUtilsExt.getString(mxItem.get("syyhzc")));
                discountMap.put("yhzc", StringUtilsExt.getString(mxItem.get("yhzc")));
                discountMap.put("mslx", StringUtilsExt.getString(mxItem.get("mslx")));

                discountMap.put("hsje", -Math.abs(zkje));
                discountMap.put("tax",tax);

                //对单价、税额、金额进行计算
                mapTaxCalculated = taxCalculated(String.valueOf(-Math.abs(zkje)), tax);

                discountMap.put("bhsje", mapTaxCalculated.get("bhsje"));
                discountMap.put("se", mapTaxCalculated.get("se"));
                list.add(discountMap);
            }
        }
        return list;
    }

    /**
     * 曹冰
     * 计算税额
     * 2020-3-21
     */
    private  static Map taxCalculated(String je, String tax) {
        Map map = new HashMap();
        //含税金额
        Double hsje = MathUtils.round(NumberUtils.toDouble(je), 2);
        //税率
        Double sl = MathUtils.round(NumberUtils.toDouble(tax), 3);
        //税率为0时，含税与不含税是一样的，不处理
        if (sl == 0) {
            map.put("bhsje", hsje);
            map.put("se", "0.00");
            return map;
        } else {
            //不含税金额:不含税金额(保留两位)=含税金额/(1+税率)
            Double bhsje = MathUtils.round(hsje / (1 + sl),2);
            //税额=含税金额-不含税金额
            Double se = MathUtils.round(hsje - bhsje,2);

            map.put("bhsje", bhsje);
            map.put("se", se);
        }

        return map;
    }

	// 发票状态转换为中文
	public static String convertFpztToZh(String fpzt){
		if(StringUtil.isEmpty(fpzt)){
			return "";
		}
		String zh = fpzt;
		switch (fpzt){
			case "00":
				zh="正数发票";
				break;
			case "01":
				zh="负数发票";
				break;
			case "02":
				zh="空白作废发票";
				break;
			case "03":
				zh="正数作废发票";
				break;
			case "04":
				zh="负数作废发票";
				break;
		}
		return zh;
	}

	public static String getGforXfxx(String tspz, String first, String second){
		String xfgxxx = first;
		if("02".equals(tspz)){
			xfgxxx = second;
		}
		return xfgxxx;
	}

	public static String convertQdbzToZh(String qdbz){
		if(StringUtil.isEmpty(qdbz)){
			return "";
		}
		String zh = qdbz;
		switch (qdbz){
			case "0":
				zh="否";
				break;
			case "1":
				zh="是";
				break;
		}
		return zh;
	}

	public static String convertDybzToZh(String dybz){
		if(StringUtil.isEmpty(dybz)){
			return "";
		}
		String zh = dybz;
		switch (dybz){
			case "0":
				zh="已打印";
				break;
			case "1":
				zh="未打印";
				break;
		}
		return zh;
	}

	public static String convertFpdmhm(String fpzt, String fpdmhm){
		if(StringUtil.isEmpty(fpzt)){
			return "";
		}
		String zh = fpzt;
		switch (fpzt){
			case "00":
				zh="";
				break;
			case "01":
				zh=fpdmhm;
				break;
			case "02":
				zh=fpdmhm;
				break;
			case "03":
				zh="";
				break;
			case "04":
				zh=fpdmhm;
				break;
		}
		return zh;
	}
	
	/**
	　* @description: 获取需要认证的发票类型
	　* @return List
	　* @author tianjifei
	　* @date 2021/6/16 17:58 
	　*/
	public static List<String> getNeedAuthFplxdm(){
		return Arrays.asList(FPUtil.NEED_AUTH_FPLXDM.split(","));
	}
	/**
	 　* @description: 获取可以抵扣的发票类型
	 　* @return List
	 　* @author tianjifei
	 　* @date 2021/6/16 17:58
	 　*/
	public static List<String> getNeedDkFplxdm(){
		return Arrays.asList(FPUtil.NEED_DK_FPLXDM.split(","));
	}
	/**
	  * @Description:获取五菱可记账的发票类型
	  * @Param: 
	  * @return: List
	  * @Author: tianjifei
	  * @Date: 2021/7/13 0013 10:29
	  */
	public static List<String> getBookKeepingInvoiceTypesForWL(){
		return Arrays.asList(FPUtil.BOOK_KEEPING_INVOICE_TYPE_WL.split(","));
	}

	/**
	 * 将新的发票类型代码转换成老的
	 * @param newFplxdm
	 * @return
	 */
	public static String convertNewFplxdmToOld(String newFplxdm,int supplierType){
		if(supplierType == 2) {//全电平台
			switch (newFplxdm) {
				case "01":
					return "004";  //  增值税专用发票
				case "03":
					return "005";  //  机动车销售统一发票
				case "04":
					return "007";  //  增值税普通发票
				case "08":
					return "028";  //  增值税电子专用发票
				case "10": //增值税电子普通发票
					return "026";//增值税普通发票（电子）
				case "81":
					return "31";  //  全电票（增值税专用发票）
				case "82":
					return "32";  //  全电票（普通发票）
				case "83":
					return "005";  //  机动车销售统一发票
				case "85"://  纸质发票（增值税专用发票）？？
					return "004";//增值税专用发票
				case "86"://  纸质发票（普通发票）？？
					return "007";//增值税普通发票
				default:
					return newFplxdm;
			}
		}else{//发票综合服务平台
			switch (newFplxdm) {
				case "01":
					return "004";  //  增值税专用发票
				case "04":
					return "007";  //  增值税普通发票
				case "10": //增值税普通发票（电子）
					return "026";//增值税普通发票（电子）
				case "11": //增值税普通发票（卷式）
					return "025";//增值税普通发票（卷式）
				case "14": //道路通行费电子普通发票
					return "092";//通行费发票？？？？
				case "15": //二手车销售统一发票
					return "006";//二手车销售统一发票
				case "24": //出口转内销发票
					return "093";//出口转内销发票
				default:
					return newFplxdm;
			}
		}
	}

	/**
	 * 鉴别发票的类型 004-专票  007-普票  025-卷票  026-电子发票 005 机动车发票 006 二手车统一销售发票
	 * @param fpdm 发票代码
	 * @return
	 */
	public static String identifyCategory(String fpdm,String fplxdm){
		String fplx ="000";
		String fpdmCut="";
		if(fpdm.length() == 12){
			fpdmCut = fpdm.substring(10,12);
			if("2".equals(fpdm.substring(7,8))){
				fplx ="005";
			}
			if("04".equals(fpdmCut) || "05".equals(fpdmCut)){
				fplx ="007";
			}else if("11".equals(fpdmCut)){
				fplx ="026";
			}else if("12".equals(fpdmCut)){
				fplx ="092";
			}else if("17".equals(fpdmCut)){  // 二手车统一销售发票
				fplx ="006";
			}else if("06".equals(fpdmCut) || "07".equals(fpdmCut)){
				fplx ="025";
			}else if("13".equals(fpdmCut)){ // 电子专票
				fplx ="028";
			}
		}else if(fpdm.length() == 10){
			fpdmCut = fpdm.substring(8,9);
			if("3".equals(fpdmCut) || "6".equals(fpdmCut) || "7".equals(fpdmCut) || "4".equals(fpdmCut)){ // 4与7都可能为专票
				fplx ="004";
			}else if("2".equals(fpdmCut) || "5".equals(fpdmCut)){
				fplx ="007";
			}
		}
		// 全电发票处理
		if("81".equals(fplxdm)){
			fplx ="31";
		}else if("82".equals(fplxdm)){
			fplx ="32";
		}
		return fplx;
	}

	/**
	 *
	 * @param fplx   发票类型
	 * @param dqlx   当前类型 1 抵账库  2 发票池  3 合力
	 * @param zhlx   转换类型 1 抵账库  2 发票池  3 合力
	 */
	public static String invoiceTypeConversion(String fplx,int dqlx,int zhlx) {
		if (dqlx == 1 && zhlx == 2) {
			switch (fplx) {
				case "004":
					return "10100"; //  增值税专用发票
				case "005":
					return "10104";  //  机动车销售统一发票
				case "006":
					return "10105";  //  二手车销售统一发票
				case "007":
					return "10101";  //  增值税普通发票
				case "092":
					return "10204";  //  通行费发票
				case "028":
					return "10107";  //  增值税电子专用发票
				case "17":
					return "17";      //  海关缴款书
				case "026":
					return "10102";  //  增值税普通发票（电子）
				case "025":
					return "10103";  //  增值税普通发票（卷式）
				case "31":
					return "1010901";	// 全电专票
				default:
					return "";
			}
		} else if (dqlx == 1 && zhlx == 3) {
			switch (fplx) {
				case "004":
					return "01";  //  增值税专用发票
				case "005":
					return "03";  //  机动车销售统一发票
				case "006":
					return "15";  //  二手车销售统一发票
				case "007":
					return "04";  //  增值税普通发票
				case "009":
					return "02";  //  货运运输业增值税专用发票
				case "092":
					return "14";  //  通行费发票
				case "028":
					return "08";  //  增值税电子专用发票
				case "17":
					return "17";      //  海关缴款书
				case "026":
					return "10";  //  增值税普通发票（电子）
				case "025":
					return "11";  //  增值税普通发票（卷式）
				case "31":
					return "08xdp";	//全电专票
				default:
					return "";
			}
		} else if (dqlx == 2 && zhlx == 1) {
			switch (fplx) {
				case "10100":
					return "004";  //  增值税专用发票
				case "10104":
					return "005";  //  机动车销售统一发票
				case "10105":
					return "006";  //  二手车销售统一发票
				case "10101":
					return "007";  //  增值税普通发票
				case "10204":
					return "092";  //  通行费发票
				case "10107":
					return "028";  //  增值税电子专用发票
				case "17":
					return "17";      //  海关缴款书
				case "10102":
					return "026";  //  增值税普通发票（电子）
				case "10103":
					return "025";  //  增值税普通发票（卷式）
				case "1010901":
					return "31";  //  全电专票
				default:
					return "";
			}
		} else if (dqlx == 2 && zhlx == 3) {
			switch (fplx) {
				case "10100":
					return "01";  //  增值税专用发票
				case "10104":
					return "03";  //  机动车销售统一发票
				case "10105":
					return "15";  //  二手车销售统一发票
				case "10101":
					return "04";  //  增值税普通发票
				case "10204":
					return "14";  //  通行费发票
				case "10107":
					return "08";  //  增值税电子专用发票
				case "17":
					return "17";      //  海关缴款书
				case "10102":
					return "10";  //  增值税普通发票（电子）
				case "10103":
					return "11";  //  增值税普通发票（卷式）
				case "1010901":
					return "08xdp";  //  全电专票
				default:
					return "";
			}
		} else if (dqlx == 3 && zhlx == 1) {
			switch (fplx) {
				case "01":
					return "004";  //  增值税专用发票
				case "03":
					return "005";  //  机动车销售统一发票
				case "15":
					return "006";  //  二手车销售统一发票
				case "04":
					return "007";  //  增值税普通发票
				case "02":
					return "009";  //  货运运输业增值税专用发票
				case "14":
					return "092";  //  通行费发票
				case "08":
					return "028";  //  增值税电子专用发票
				case "17":
					return "17";      //  海关缴款书
				case "10":
					return "026";  //  增值税普通发票（电子）
				case "11":
					return "025";  //  增值税普通发票（卷式）
				case "08xdp":
					return "31";  //  全电专票
				case "10xdpzz":
					return "007";  //  数电纸质普票
				case "08xdpzz":
					return "004";  //  数电纸质专票
				default:
					return "";
			}
		} else if (dqlx == 3 && zhlx == 2) {
			switch (fplx) {
				case "01":
					return "10100";  //  增值税专用发票
				case "03":
					return "10104";  //  机动车销售统一发票
				case "15":
					return "10105";  //  二手车销售统一发票
				case "04":
					return "10101";  //  增值税普通发票
				case "14":
					return "10204";  //  通行费发票
				case "08":
					return "10107";  //  增值税电子专用发票
				case "17":
					return "17";      //  海关缴款书
				case "10":
					return "10102";  //  增值税普通发票（电子）
				case "11":
					return "10103";  //  增值税普通发票（卷式）
				case "08xdp":
					return "1010901";  //  全电专票
				default:
					return "";
			}
		}
		return "";
	}

	//合力中税发票类型转换为百望类型
	public static String hllxToBwlx(String fplxdm){
		String bwlx=fplxdm;
		//01 增值税专用发票
		//02 货运运输业增值税专用发票
		//03 机动车增值税专用发票
		//14 通行费发票
		//17海关缴款书发票
		if("01".equals(fplxdm)){
			bwlx="004";
		} else if("02".equals(fplxdm)){
			//不处理
		}else if("03".equals(fplxdm)){
			bwlx="005";
		}else if("04".equals(fplxdm)){
			bwlx="007";
		}else if("14".equals(fplxdm)){
			bwlx="092";
		}else if("08".equals(fplxdm)){
			bwlx="028";
		}else if("10".equals(fplxdm)){
			bwlx="026";
		}else if("11".equals(fplxdm)){
			bwlx="025";
		}
		return bwlx;
	}

	/**
	 * 小数位处理  大于等于2位不处理  小于2位保留两位小数
	 * @param str
	 * @return
	 */
	public static String handleDecimal(String str){
		String result;
		if(StringUtil.isEmpty(str)){
			return str;
		}
		if (str.contains(".")) {
			//是小数
			int num = str.length() - (str.indexOf(".") + 1);
			if (num < 2) {
				//小数位 小于2位  保存两位小数
				result = String.format("%.2f", Double.parseDouble(str));
			}else {
				//小数位 大于等于2位 不处理
				result = str;
			}
		}else {
			//是整数
			result = str + ".00";
		}
		return result;
	}

	/**
	 * 合力接口根据认证结果的code转换对应的msg
	 */
	public static String getFpRzMsg(String code){
		String msg = "";
		if (org.apache.commons.lang3.StringUtils.isBlank(code)){
			return msg;
		}
		switch (code){
			case "1":
				msg = "成功";
				break;
			case "2":
				msg = "无此票";
				break;
			case "3":
				msg = "该票异常无法认证";
				break;
			case "4":
				msg = "该票已认证过";
				break;
			case "5":
				msg = "该票已经逾期无法认证";
				break;
			case "7":
				msg = "申请认证月份已过期(传入的属期，小于企业的当前税款所属期)";
				break;
			case "8":
				msg = "认证操作执行异常";
				break;
			case "10":
				msg = "该票超出可操作开票日期范围上限";
				break;
			case "11":
				msg = "该票已作废";
				break;
			case "12":
				msg = "该票已红冲";
				break;
			case "13":
				msg = "未申报，属期尚未切换(传入的属期，大于企业的当前税款所属期)";
				break;
			case "15":
				msg = "失控发票";
				break;
			case "16":
				msg = "红字发票不能认证";
				break;
			case "17":
				msg = "该发票类型不符合退税认证条件";
				break;
			case "18":
				msg = "有效税额不合法";
				break;
			case "19":
				msg = "已勾选";
				break;
			case "20":
				msg = "当期已锁定勾选";
				break;
			case "21":
				msg = "管理状态异常";
				break;
			case "23":
				msg = "发票当前未勾选(取消 勾选/不抵扣勾选)";
				break;
			case "24":
				msg = "勾选属期非当前属期,不能取消(取消 勾选/不抵扣勾选)";
				break;
			case "25":
				msg = "当前勾选用途非抵扣勾选(取消勾选)";
				break;
			case "26":
				msg = "当前勾选用途非不抵扣勾选（取消不抵扣勾选）";
				break;
			case "27":
				msg = "发票状态不合规";
				break;
			case "31":
				msg = "数据校验异常";
				break;
			case "32":
				msg = "认证期限校验异常";
				break;
			default:
		}
		return msg;
	}

	/**
	 * 抵账库发票类型代码转汉字
	 * @return
	 */
	public static String dzkFpdm2String (String invoiceType) {
		String invoiceTypeName = "";
		if (org.apache.commons.lang3.StringUtils.isBlank(invoiceType)) {
			return invoiceType;
		}
		switch (invoiceType){
			case "004":
				invoiceTypeName = "增值税专用发票";
				break;
				case "005":
				invoiceTypeName = "机动车销售统一发票";
				break;
			case "092":
				invoiceTypeName = "电子通行费发票";
				break;
			case "028":
				invoiceTypeName = "增值税电子专用发票";
				break;
			case "17":
				invoiceTypeName = "海关缴款书";
				break;
			case "31":
				invoiceTypeName = "全电专票";
				break;
			default:

		}
		return invoiceTypeName;
	}

	/**
	 * 抵账库发票状态转汉字
	 * @return
	 */
	public static String dzkFpzt2String (String status) {
		String statusDesc = "";
		if (org.apache.commons.lang3.StringUtils.isBlank(status)) {
			return statusDesc;
		}
		switch (status){
			case "0":
				statusDesc = "正常";
				break;
			case "1":
				statusDesc = "作废";
				break;
			case "2":
				statusDesc = "红冲";
				break;
			case "3":
				statusDesc = "失控";
				break;
			case "4":
				statusDesc = "异常";
				break;
			case "21":
				statusDesc = "全额冲红";
				break;
			case "22":
				statusDesc = "部分冲红";
				break;
			default:

		}
		return statusDesc;
	}

	/**
	 * 差额征税发票获取差额征税的金额
	 * @param bz
	 * @return
	 */
	public static BigDecimal getDiffAmount(String bz) {
		String regex = "\\d+(\\.\\d+)?";
		Pattern compile = Pattern.compile(regex);
		String substring = bz.substring(bz.indexOf("差额征税"));
		System.out.println(substring);
		Matcher matcher = compile.matcher(substring);
		String matchStr = "";
		while (matcher.find()) {
			matchStr = matcher.group();
			break;
		}
		BigDecimal result = BigDecimal.ZERO;
		if (org.apache.commons.lang3.StringUtils.isNotBlank(matchStr)) {
			result = new BigDecimal(matchStr);
		}
		return result;
	}

	/**
	 * 特殊票种转换位中文标识
	 *
	 * @param tspz
	 * @return
	 */
	public static String convertTspzToZh(String tspz) {
		if (StringUtil.isEmpty(tspz)) {
			return "";
		}
		String zh = tspz;
		switch (tspz) {
			case "00":
				zh = "正常发票";
				break;
			case "02":
				zh = "收购发票";
				break;
			case "08":
				zh = "成品油";
				break;
			case "12":
				zh = "机动车";
				break;
			case "16":
				zh = "矿产品";
				break;
		}
		return zh;
	}

}
